package edu.drexel.jrexel2d.objects2D;

import java.io.Serializable;
import java.util.ArrayList;

import edu.drexel.jrexel2d.animation.Sprite;
import edu.drexel.jrexel2d.input.CharacterActions;
import edu.drexel.jrexel2d.objects2D.actions.Moveable;
import edu.drexel.jrexel2d.physics.PhysicsEngine;

public class Player extends Object2D implements Moveable, Serializable {
	private int playerId; // Which number player this is

	private CharacterActions lastAction;
	private ArrayList<CharacterActions> curActions;
	
	private int pickedObjectId = -1;

	public Player(Sprite s, int i, int j) {
		super(s, i);
		playerId = j;
		curActions = new ArrayList<CharacterActions>();
		setMovable(true); //all players will be movable
	}

	public int getPlayerId() {
		return playerId;
	}

	public void shift(int x, int y) {
		super.shift(x, y);
		refPhysicsEngine.objectMove(this.id, x, y);
	}

	@Override
	public void moveUp() {
		shift(0, -5);
		lastAction = CharacterActions.MOVE_UP;
		curActions.add(CharacterActions.MOVE_UP);
	}

	@Override
	public void moveDown() {
		shift(0, 5);
		lastAction = CharacterActions.MOVE_DOWN;
		curActions.add(CharacterActions.MOVE_DOWN);
	}

	@Override
	public void moveLeft() {
		shift(-5, 0);
		lastAction = CharacterActions.MOVE_LEFT;
		curActions.add(CharacterActions.MOVE_LEFT);
		this.setSheet("runLeft");
	}

	@Override
	public void moveRight() {
		shift(5, 0);
		lastAction = CharacterActions.MOVE_RIGHT;
		curActions.add(CharacterActions.MOVE_RIGHT);
		this.setSheet("runRight");
	}

	public CharacterActions getLastAction() {
		return lastAction;
	}

	public void setLastAction(CharacterActions lastAction) {
		this.lastAction = lastAction;
	}

	public ArrayList<CharacterActions> getActions() {
		return curActions;
	}

	public void clearActions() {
		curActions.clear();
	}

	@Override
	public void jump() {
		if (!isJumping()) {

			refPhysicsEngine.playerJump(this.id);
			lastAction = CharacterActions.JUMP;
			curActions.add(CharacterActions.JUMP);
		}
	}

	public boolean isJumping() {
		return refPhysicsEngine.getPhysicsObjectById(this.id).isJumping();
	}

	public Point2D getJumpPoint() {
		return refPhysicsEngine.getPhysicsObjectById(this.id).getJumpPoint();
	}

	public Point2D getBase() {
		if (isJumping()) {
			return new Point2D(getJumpPoint(), 0, getHeight() / 2);
		}
		return super.getBase();
	}

	public void animate() {
		if (curActions.isEmpty() && !current.getName().equals("idle")) {
			this.setSheet("idle");
		} else {
			super.animate();
		}
	}

	@Override
	public void pickup() {

		//Can't pick an object up if already holding an object
		if (!this.isHoldingObject()) {

			int pickableObjId = refPhysicsEngine.getPickableObject(
					this.getLocation(), this.id);

			if (pickableObjId >= 0) {
				refPhysicsEngine.pickupObject(this.id, pickableObjId);
			}
		}
	}

	public boolean isHoldingObject() {
		boolean holdingAnObject = false;

		if (pickedObjectId >= 0) {
			holdingAnObject = true;
		}

		return holdingAnObject;
	}

	public int getHeldObjectId() {
		return pickedObjectId;
	}

	public void setHeldObjectId(int heldObjId) {
		pickedObjectId = heldObjId;
	}

	@Override
 	public void throwObject() {

		//Can only throw if holding an object
		if (isHoldingObject()) {
			//shouldn't throw another object if thrower 

			//is in the middle of being thrown or rolled.
			if(!this.isThrown() || !this.isRolled()){
				refPhysicsEngine.throwObject(this.id, getHeldObjectId());	

			}

		}
	}
	
	@Override
	public void rollObject(){
		
		//Can only roll if holding an object
		if(isHoldingObject()){
			//shouldn't roll another object if roller 
			//is in the middle of being thrown or rolled.
			if(!this.isThrown() || !this.isRolled()){
				refPhysicsEngine.rollObject(this.id, getHeldObjectId());	
			}			

		}
	}

}
